#include "filebrowsercommand.h"
#include "filecommandcreator.h"
#include "cdcommand.h"
#include "downloadcommand.h"
#include "messagepack.h"
#include "formatcommand.h"
#include "deletefilecommand.h"

#include <QByteArray>
#include <QDebug>
#include <boost/function.hpp>

int GetSeq(boost::shared_ptr<MessagePack> messagePack)
{
	int seq;
	if(!messagePack->getData("Seq", seq))
	{
		qDebug()<<"Get seq from message pack error";
		return 0;
	}
	return seq;
}

FileBrowserCommand* CDCommandCreator(boost::shared_ptr<MessagePack> messagePack)
{
	QString dir;
	if(!messagePack->getData("Dir", dir))
	{
		qDebug()<<"Get dir from message pack error";
		return NULL;
	}

	CDCommand* cdCommand = new CDCommand(dir);
	return cdCommand;
}

FileBrowserCommand* DownloadCommandCreator(boost::shared_ptr<MessagePack> messagePack)
{
	int transferId;
	QString filePath,saveFilePath;
	if(!messagePack->getData("TransferId", transferId))
	{
		qDebug()<<"Get transfer id from message pack error";
		return NULL;
	}
	if(!messagePack->getData("FilePath", filePath))
	{
		qDebug()<<"Get file path from message pack error";
		return NULL;
	}
	if(!messagePack->getData("SaveFilePath", saveFilePath))
	{
		qDebug()<<"Get save file path from message pack error";
		return NULL;
	}

	DownloadCommand* downloadCommand = new DownloadCommand(transferId, filePath, saveFilePath);
	return downloadCommand;
}

FileBrowserCommand* FormatCommandCreator(boost::shared_ptr<MessagePack> messagePack)
{
	QString formatDrive;
	if(!messagePack->getData("DriveLetter", formatDrive))
	{
		qDebug()<<"Get format drive from message pack error";
		return NULL;
	}

	FormatCommand* formatCommand = new FormatCommand(formatDrive);
	return formatCommand;
}

FileBrowserCommand* DeleteFileCommandCreator(boost::shared_ptr<MessagePack> messagePack)
{
	QString filePath;
	if(!messagePack->getData("FilePath", filePath))
	{
		qDebug()<<"Get file path from message pack error";
		return NULL;
	}

	DeleteFileCommand* deleteFileCommand = new DeleteFileCommand(filePath);
	return deleteFileCommand;
}

static QHash<unsigned long, FileBrowserCommand* (* )(boost::shared_ptr<MessagePack>)> CodeToCreator;

void InitCodeToCreator()
{
	CodeToCreator.insert(CDCommandCode, CDCommandCreator);
	CodeToCreator.insert(DownloadCode, DownloadCommandCreator);
	CodeToCreator.insert(FormatCode, FormatCommandCreator);
	CodeToCreator.insert(DeleteFileCode, DeleteFileCommandCreator);
}

boost::shared_ptr<FileBrowserCommand> RestoreFileCommand(const QByteArray& messRawData)
{
	static bool first = true;
	if(first)
	{
		InitCodeToCreator();
		first = false;
	}
	boost::shared_ptr<MessagePack> messagePack = MessagePack::createMessagePack();
	if( !messagePack->unmarshal(messRawData) )
	{
		qDebug()<<"Unnmarshal message error";
		return boost::shared_ptr<FileBrowserCommand>();
	}

	if(!CodeToCreator.contains(messagePack->getCode()))
	{
		return  boost::shared_ptr<FileBrowserCommand>();
	}
	boost::shared_ptr<FileBrowserCommand> command( CodeToCreator[messagePack->getCode()](messagePack) );

	int seq = GetSeq(messagePack);
	if(seq == 0)
	{
		return boost::shared_ptr<FileBrowserCommand>();
	}
	command->setSeq(seq);
	return command;
}
